package com.szbber.commen.api

import com.blankj.utilcode.utils.LogUtils
import com.google.gson.Gson
import com.szbber.commen.base.Constant
import com.szbber.commen.utils.CommonUtil
import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okio.Buffer
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit


object ApiFactory {

    // 日志拦截器
    private val mLoggingInterceptor: Interceptor by lazy { LoggingInterceptor() }

    // OkHttpClient客户端
    private val mClient: OkHttpClient by lazy { newClient() }

//    private val encr: ResponseDecryptInterceptor by lazy { ResponseDecryptInterceptor() }
//    private val encrypt: RequestEncryptInterceptor by lazy { RequestEncryptInterceptor() }
//    private val encrypts: EncryptInterceptor by lazy { EncryptInterceptor() }

    /**
     * 创建API Service接口实例
     */
    fun <T> createService(clazz: Class<T>): T =
        Retrofit.Builder().baseUrl(Constant.API_BASE_URL).client(mClient)
            .addConverterFactory(GsonConverterFactory.create(Gson()))
            .build().create(clazz)

    /**
     * OkHttpClient客户端
     */
    private fun newClient(): OkHttpClient = OkHttpClient.Builder().apply {
        connectTimeout(50, TimeUnit.SECONDS)// 连接时间：30s超时
        readTimeout(50, TimeUnit.SECONDS)// 读取时间：10s超时
        writeTimeout(50, TimeUnit.SECONDS)// 写入时间：10s超时
        addInterceptor(mLoggingInterceptor)    // 启用日志过滤器
        addInterceptor(mHeaderInterceptor)
        addInterceptor(MoreBaseUrlInterceptor)
//        addInterceptor(encr)
    }.build()

    private var mHeaderInterceptor =
        Interceptor { chain: Interceptor.Chain ->
            val builder = chain.request().newBuilder()
            builder.addHeader(
                "User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.108 Safari/537.36 2345Explorer/8.0.0.13547"
            )
            builder.addHeader("Cache-Control", "max-age=0")
            builder.addHeader("Content-Type", "application/json; charset=UTF-8")
            builder.addHeader("Upgrade-Insecure-Requests", "1")
            builder.addHeader("X-Requested-With", "XMLHttpRequest")
            builder.addHeader(
                "Cookie",
                "uuid=\"w:f2e0e469165542f8a3960f67cb354026\"; __tasessionId=4p6q77g6q1479458262778; csrftoken=7de2dd812d513441f85cf8272f015ce5; tt_webid=36385357187"
            )
            builder.addHeader("X-Access-Token", "BS919 293DCFC6BB2ED176140B91CB267C9442")

            builder.addHeader(
                "Authorization",
                "Api 1441950074075422722_3db568a8-5882-4ac7-9c48-49dbb8c201d9"
            )
            chain.proceed(builder.build())

        }


//    class ResponseDecryptInterceptor : Interceptor {
//        override fun intercept(chain: Interceptor.Chain): Response {
//            val request = chain.request()
//            val response = chain.proceed(request)
//            lateinit var newResponse: Response
//            if (response.isSuccessful) {
//                val responseBody = response.body
//                if (responseBody != null) {
//                    /*开始解密*/
//                    try {
//                        val source = responseBody.source()
//                        source.request(java.lang.Long.MAX_VALUE)
//                        val buffer = source.buffer()
//                        var charset = Charset.forName("UTF-8")
//                        val contentType = responseBody.contentType()
//                        if (contentType != null) {
//                            charset = contentType.charset(charset)
//                        }
//                        var bodyString = buffer.clone().readString(charset)
//                        bodyString = bodyString.replace("\"", "")
//                        val responseData = AESCBCUtil.decrypt(bodyString)
//                        /*将解密后的明文返回*/
//                        val newResponseBody = ResponseBody.create(contentType, responseData.trim())
//                         newResponse = response.newBuilder().body(newResponseBody).build()
//                    } catch (e: Exception) {
//                        /*异常说明解密失败 信息被篡改 直接返回即可 */
//                        LogUtils.e("解密异常====》${e}")
//                        return response
//                    }
//                } else {
//                    LogUtils.i("响应体为空")
//                }
//            }
//            return newResponse
//        }
//    }

//    class EncryptInterceptor : Interceptor {
//        @Throws(IOException::class)
//        override fun intercept(chain: Interceptor.Chain): Response {
//            var request: Request = chain.request()
//            //这个是请求方法
//            request = encrypt(request)  //加密方法
//            return chain.proceed(request)
//        }
//    }

    private var MoreBaseUrlInterceptor: Interceptor =
        Interceptor { chain -> //获取原始的originalRequest
            val originalRequest = chain.request()
            //获取老的url
            val oldUrl = originalRequest.url
            //获取originalRequest的创建者builder
            val builder = originalRequest.newBuilder()
            val baseURL = CommonUtil.getBaseUrl().toHttpUrlOrNull()
            //重建新的HttpUrl，需要重新设置的url部分
            val newHttpUrl = oldUrl.newBuilder()
                .scheme(baseURL!!.scheme)
                .host(baseURL.host)
                .port(baseURL.port)
                .build()

            //获取处理后的新newRequest
            val newRequest =
                builder.url(newHttpUrl)
                    .build()
            chain.proceed(newRequest)

        }



    /**
     * 日志拦截器
     */
    private class LoggingInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val mediaType = "text/plain; charset=utf-8".toMediaTypeOrNull()
            val UTF8 = Charset.forName("UTF-8")
            val request = chain.request()
            val t1 = System.nanoTime() //请求发起的时间
            val map: MutableMap<String, String?> =
                HashMap()
            for (i in request.url.queryParameterNames.indices) {
                map[request.url.queryParameterName(i)] = request.url.queryParameterValue(i)
            }
            val response = chain.proceed(request)
            val t2 = System.nanoTime() //收到响应的时间
            val responseBody = response.peekBody(1024 * 1024.toLong())
            val requestBody = request.body
            var body: String? = null
            if (requestBody != null) {
                val buffer = Buffer()
                requestBody.writeTo(buffer)
                var charset: Charset = UTF8
                val contentType: MediaType? = requestBody.contentType()
                if (contentType != null) {
                    charset = contentType.charset(UTF8)!!
                }
                body = buffer.readString(charset)
            }

            LogUtils.e(
                String.format(
                    "接收响应: [%s] %n返回解密json : [%s] %n请求参数: [%s] %n请求body: [%s] %n响应时间[%.1fms]",
                    response.request.url,
                    responseBody.string().trim(),
                    transMapToString(map),
                    body,
                    (t2 - t1) / 1e6
                )
            )
            return response
        }
    }

    fun transMapToString(map: Map<*, *>): String {
        var entry: Map.Entry<*, *>
        val sb = StringBuilder()
        val iterator: Iterator<*> = map.entries.iterator()
        while (iterator.hasNext()) {
            entry = iterator.next() as Map.Entry<*, *>
            sb.append(entry.key.toString()).append(" == ")
                .append(if (null == entry.value) "" else entry.value.toString())
                .append(if (iterator.hasNext()) "\n" else "")
        }
        return sb.toString()
    }

    fun formatJson(jsonStr: String?): String {
        if (null == jsonStr || "" == jsonStr) {
            return ""
        }
        val sb = StringBuilder()
        var last = '\u0000'
        var current = '\u0000'
        var indent = 0
        for (i in 0 until jsonStr.length) {
            last = current
            current = jsonStr[i]
            when (current) {
                '{', '[' -> {
                    sb.append(current)
                    sb.append('\n')
                    indent++
                    addIndentBlank(sb, indent)
                }
                '}', ']' -> {
                    sb.append('\n')
                    indent--
                    addIndentBlank(sb, indent)
                    sb.append(current)
                }
                ',' -> {
                    sb.append(current)
                    if (last != '\\') {
                        sb.append('\n')
                        addIndentBlank(
                            sb,
                            indent
                        )
                    }
                }
                else -> sb.append(current)
            }
        }
        return sb.toString()
    }

    private fun addIndentBlank(sb: StringBuilder, indent: Int) {
        for (i in 0 until indent) {
            sb.append('\t')
        }
    }

}